import json
import time

from django.shortcuts import render
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from myadmin.models import Admin, Role, Resource, Interface, ResourceMutex, Position
from myadmin.serial import AdminSerializer, RoleSerializer, ResourceSerializer, ResourceMutexSerializer, PositionSerializer
from dingxiang_doctor.utils.myjwt import myjwt
from django_redis import get_redis_connection


# Create your views here.
class LoginView(APIView):
    def post(self, request):
        name = request.data.get('name')
        password = request.data.get('password')
        admin = Admin.objects.filter(name=name, password=password).first()
        if admin:
            # 1080s
            # 设置token载荷及其过期时间
            token = myjwt.jwt_encode({'data': {'id': admin.id, 'role': admin.role.id, 'exp': int(time.time()) + 10800}})
            role_id = admin.role_id
            # if role_id == 1:
            # 获取角色对应资源
            role = Role.objects.get(id=role_id)
            resources = Resource.objects.filter(role=role)
            serializer = ResourceSerializer(resources, many=True)

            # 通过位运算获取角色资源
            role = Role.objects.get(id=role_id)
            # 获取角色权限值
            permission = role.permission
            print(permission)
            # 获取带有权限值的资源列表
            resource_list = Resource.objects.exclude(permission=None)
            print(resource_list)
            # 初始化角色权限拥有资源列表
            permission_resource_list = []
            # 遍历资源列表，判断哪些资源属于角色
            for item in resource_list:
                # 如果资源的权值大于用户现有权值，说明后面的资源权值全部大于用户权值，直接结束循环
                if item.permission > permission:
                    break
                if (permission & item.permission) > 0:
                    permission_resource_list.append(ResourceSerializer(item).data)
            print("权限值资源列表：", permission_resource_list)

            # 修改返回格式
            data_list = []
            pid_list = []
            url_list = []  # 新增前端路由列表
            # for i in serializer.data:  # 使用resource外键获取菜单
            for i in permission_resource_list:  # 使用权限值列表获取菜单
                data_list.append(
                    {"id": i["id"], "name": i["name"], "url": i["url"], "pid": i["pid"], "pname": i["pname"]})
                if {"pid": i["pid"], "pname": i["pname"], "son": []} not in pid_list:
                    pid_list.append({"pid": i["pid"], "pname": i["pname"], "son": []})
            # print(pid_list)

            for item in data_list:
                for j in pid_list:
                    if item["pid"] == j["pid"]:
                        j["son"].append({"id": item["id"], "name": item["name"], "url": item["url"]})
                        url_list.append(item["url"])
                        break
            # 使每个角色均可访问admin页
            url_list.append("/admin")

            # 获取资源的接口列表
            interface_list = []
            for i in resources:
                interfaces = Interface.objects.filter(resource=i)
                for j in interfaces:
                    interface_list.append(j.url)

            redis = get_redis_connection("admin")
            pipeline = redis.pipeline()
            pipeline.multi()
            pipeline.set(f"dingxiang_role_{role_id}", json.dumps({"role": role.id, "interface_list": interface_list}))
            pipeline.execute()

            return Response({'message': 'Login successful', 'admin': AdminSerializer(admin).data, "token": token,
                             "pid_list": pid_list, "url_list": url_list})
        else:
            return Response({'message': 'Invalid credentials'}, status=400)


# 创建管理员
class CreateAdminView(CreateAPIView):
    queryset = Admin.objects.all()
    serializer_class = AdminSerializer

# 创建角色
class CreateRoleView(CreateAPIView):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer

# 获取角色列表
class RoleListView(ListAPIView):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['type']

# 通过角色id获取其资源
class GetResourceByRoleView(APIView):
    def get(self, request):
        role_id = request.query_params.get('role_id')
        print(role_id)
        role = Role.objects.get(id=role_id)

        # 从角色资源表中获取角色对应资源
        resources = Resource.objects.filter(role=role)
        serializer = ResourceSerializer(resources, many=True)
        resources_list = []

        # 用权限值获取角色资源
        permission = role.permission
        resource_list = Resource.objects.exclude(permission=None)
        permission_resource_list = []
        for item in resource_list:
            # 如果资源的权值大于用户现有权值，说明后面的资源权值全部大于用户权值，直接结束循环
            if item.permission > permission:
                break
            if (permission & item.permission) > 0:
                permission_resource_list.append(ResourceSerializer(item).data)

        # for item in serializer.data:  # 使用角色资源表获取资源
        for item in permission_resource_list:  # 使用权限值获取资源
            resources_list.append(item["id"])
        return Response({"data": resources_list})

# 删除角色
class DeleteRoleView(DestroyAPIView):
    queryset = Role.objects.all()
    serializer_class = RoleSerializer
    lookup_field = 'id'
    lookup_url_kwarg = 'pk'


# 创建资源
class CreateResourceView(CreateAPIView):
    queryset = Resource.objects.all()
    serializer_class = ResourceSerializer

# 获取资源列表
class ResourceListView(ListAPIView):
    serializer_class = ResourceSerializer

    def get_queryset(self):
        queryset = Resource.objects.exclude(pid=None)
        return queryset

# 获取所有职务
class PositionListView(ListAPIView):
    queryset = Position.objects.all()
    serializer_class = PositionSerializer


# 获取用户对应菜单(已并入Login)
class GetResourceAPIView(APIView):
    def post(self, request):
        # 获取用户的角色id
        role_id = request.data.get('role_id')
        # if role_id == 1:
        # 获取角色对应资源
        role = Role.objects.get(id=role_id)
        resources = Resource.objects.filter(role=role)
        serializer = ResourceSerializer(resources, many=True)

        # 修改返回格式
        data_list = []
        pid_list = []
        url_list = []   # 新增前端路由列表
        for i in serializer.data:
            data_list.append({"id": i["id"], "name": i["name"], "url": i["url"], "pid": i["pid"], "pname": i["pname"]})
            if {"pid": i["pid"], "pname": i["pname"], "son": []} not in pid_list:
                pid_list.append({"pid": i["pid"], "pname": i["pname"], "son": []})
        # print(pid_list)

        for item in data_list:
            for j in pid_list:
                if item["pid"] == j["pid"]:
                    j["son"].append({"id": item["id"], "name": item["name"], "url": item["url"]})
                    url_list.append(item["url"])
                    break
        url_list.append("/admin")

        return Response({"pid_list": pid_list, "url_list": url_list})


# 给角色分配资源(已弃用)
class AddRoleResources(APIView):
    def post(self, request):
        role_id = request.data.get('role_id')
        resource_id = request.data.get('resource_id')
        role = Role.objects.get(id=role_id)
        # resources = Resource.objects.filter(id=resource_id)
        role.resources.add(resource_id)
        role.save()
        return Response({'message': 'Resources added successfully'})

# 修改角色资源
class UpdateRoleResources(APIView):
    def post(self, request):
        role_id = request.data.get('role_id')
        # 获取前端传来的id列表
        resource_ids = request.data.get('resource_ids')
        print("前端传来资源id：", resource_ids)

        # 互斥表(共用)
        mutex_resource = ResourceMutex.objects.filter(resource1__id__in=resource_ids)
        mutex_list = [item.resource2.id for item in mutex_resource]
        print(mutex_list)
        result = list(set(resource_ids) & set(mutex_list))
        if result:
            return Response({'message': 'Resources conflict'})

        # 通过角色资源表获取父级资源
        role = Role.objects.get(id=role_id)
        son_resource_ids = resource_ids
        if role.pid:
            p_role = role.pid
            p_resource = RoleSerializer(p_role).data
            p_resource_list = p_resource["resources"]
            print("父资源列表：", p_resource_list)
            # 减去父级资源
            son_resource_ids = list(set(resource_ids) - set(p_resource_list))

        # ----------------------------------------------------------

        # 直接通过资源权限值修改用户权限值
        # 获取资源列表对应的资源
        resource = Resource.objects.filter(id__in=resource_ids)
        # 获取用户新获得的资源权限总和
        role_permission = 0
        for item in resource:
            role_permission = role_permission | item.permission

        # 删除父角色的权限资源
        if role.pid:
            role = Role.objects.get(id=role_id)
            print("父角色权限值：", role.pid.permission)
            print("总权限值：", role_permission)
            if role.pid:
                role_permission = role_permission ^ role.pid.permission
            print(role_permission)

        role.permission = role_permission
        role.resources.set(son_resource_ids)
        role.save()
        return Response({'message': 'Resources removed successfully'})


# 退出登录
class LogoutView(APIView):
    def post(self, request):
        token = request.data.get("token")
        admin_id = myjwt.jwt_decode(token)["data"]["id"]
        print(token)
        print(admin_id)
        redis = get_redis_connection("admin")
        redis.set(f"dingxiang_admin_{admin_id}", token)
        return Response({'message': 'Logout successful'})
